package deng.ejbtx.ejb.order;

import java.io.StringReader;

import javax.annotation.Resource;
import javax.ejb.ActivationConfigProperty;
import javax.ejb.EJB;
import javax.ejb.MessageDriven;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.xml.bind.JAXB;

import org.apache.log4j.Logger;


@MessageDriven(
		messageListenerInterface = MessageListener.class,
		activationConfig = { 
			@ActivationConfigProperty(					
				propertyName = "destination", propertyValue = "queue/OrderReceiver"),
			@ActivationConfigProperty(					
				propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
			@ActivationConfigProperty(					
				propertyName = "messageSelector", propertyValue = "") 
		})
public class OrderReceiver implements MessageListener {
	private static Logger logger = Logger.getLogger(OrderReceiver.class);
	
	@EJB(beanName="OrderValidator")
	private OrderProcessor orderValidator;
	
	@EJB(beanName="OrderValidator")
	private OrderProcessor orderFulfillment;
	
	@Resource(mappedName="ConnectionFactory")
	private ConnectionFactory connectionFactory;
	
	@Override
    public void onMessage(Message message) {
		try {
			logger.info("Received message: " + message);
			Order order = convert(message);
			orderValidator.process(order);
			orderFulfillment.process(order);
			sendReceipt("Order Received. Id=" + order.getId());
		} catch (Exception e) {
			logger.error("Failed to process JMS message " + message, e);
			try {
				sendReceipt("Order failed. " + e.getMessage());
			} catch (Exception e1) {
				logger.error("Failed to send receipt.", e1);
			}
		}
    }

	private void sendReceipt(String msg) throws Exception {
		Connection connection = null;
		try {
			connection = connectionFactory.createConnection();
			Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
			Destination receiptQueue = session.createQueue("/queue/ReceiptQueue");
			MessageProducer producer = session.createProducer(receiptQueue);
			TextMessage receiptMsg = session.createTextMessage(msg);
			producer.send(receiptMsg);
		} finally {
			if (connection != null) {
				connection.close();
			}
		}
	}

	private Order convert(Message message) throws Exception {
		TextMessage txtmsg = (TextMessage)message;
		StringReader reader = new StringReader(txtmsg.getText());
		Order order = JAXB.unmarshal(reader, Order.class);
		return order;
	}
}